﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SiemensOPC;
using Opc.Ua;
using Opc.Ua.Client;
using VswService_V7.Config;
using VswService_V7.DataBase.Tables;
using System.Data;
using VswService_V7.Utility;

namespace VswService_V7.OPC.DB
{
    public class RecipeEventAddressDbData : SubscriptionDbDataBase
    {

        RecipeEventINfo recipeInfo;
        CheckMinDelay timeCheck;

        public event EventHandler<MachineStatusChangedEventArgs> MachineStatusChanged;

        public RecipeEventAddressDbData(SimaticOPCClient opc, NodeConfig nodes) : base(opc, nodes)
        {
            recipeInfo = new RecipeEventINfo();
            timeCheck = new CheckMinDelay(5);
        }

        public override void CreateSubscription()
        {
            try
            {
                opcServer.QuickAddMonitorItem(opcNodes.RecipeEventAddress.GrpoupName,
                    opcNodes.RecipeEventAddress.PublishTime,
                    opcNodes.RecipeEventAddress.SampleTime,
                    opcNodes.RecipeEventAddress.GetNodeAddress(),
                    opcNodes.RecipeEventAddress.GetNodeDisplayName(),
                    SubscriptionHandler);

                opcServer.QuickAddMonitorItem(opcNodes.RecipeInfoAddress.GrpoupName,
                    opcNodes.RecipeInfoAddress.PublishTime,
                    opcNodes.RecipeInfoAddress.SampleTime,
                    opcNodes.RecipeInfoAddress.GetNodeAddress(),
                    opcNodes.RecipeInfoAddress.GetNodeDisplayName(),
                    SubscriptionHandlerAsk);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("RecipeEventAddressDbData CreateSubscription", ex);
            }
        }

        private void SubscriptionHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
            if (notification == null)
                return;
            if (monitoredItem.DisplayName == "RecipeEventTrigger")
            {
                bool ask = false;
                if (bool.TryParse(notification.Value.Value.ToString(), out ask))
                {
                    if (ask)
                    {
                        Console.WriteLine("RecipeEventTriggered ");
                        Console.WriteLine("Millline Recoverd ");
                        if (timeCheck.ActionVaild())
                        {
                            MachineStatusChanged?.Invoke(this, new MachineStatusChangedEventArgs(true));
                            Task.Run(() => HandleNewRecipe());
                        }


                    }
                }
            }
        }


        private async Task HandleNewRecipe()
        {
            await Task.Delay(2000);


            Console.WriteLine("start record HandleNewRecipe changed");
            recipeInfo.updateDate = DateTime.Now.ToString(Formats.LongFormat);
            try
            {
                //记录downtime 回复时刻
                //DOWNTIME_TABLE.UpdateDownTimeRecord(DateTime.Now);
                //记录recipe 变更记录
                RECIPE_EVENT.NewRecipeChangedEvent(recipeInfo);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("HandleNewRecipe changed", ex);
            }

        }


        private void SubscriptionHandlerAsk(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
            if (notification == null)
                return;

            switch (monitoredItem.DisplayName)
            {
                case "Recipe_ID":
                    {
                        recipeInfo.recipeNo = notification.Value.Value.ToString();
                        break;
                    }

                case "ACC_PR_T_Pressure":
                    {
                        recipeInfo.accPressure_T = notification.Value.Value.ToString();
                        break;
                    }

                case "ACC_PR_B_Pressure":
                    {
                        recipeInfo.accPressure_B = notification.Value.Value.ToString();
                        break;
                    }

                case "Em_Cutting_Spd_1":
                    {
                        recipeInfo.emCuttingSpeed_1 = Formats.ConvertUnit(notification.Value.Value.ToString(), VswUnit.EM_Cut_SPD_L2,1);
                        break;
                    }

                case "Em_Chipload_1":
                    {
                        recipeInfo.emCuttingChipLoad_1 = Formats.ConvertUnit(notification.Value.Value.ToString(), VswUnit.EM_CHIPLOAD_L2,1);
                        break;
                    }

                case "Em_Cutting_Spd_2":
                    {
                        recipeInfo.emCuttingSpeed_2 = Formats.ConvertUnit(notification.Value.Value.ToString(), VswUnit.EM_Cut_SPD_L2,1);
                        break;
                    }

                case "Em_Chipload_2":
                    {
                        recipeInfo.emCuttingChipLoad_2 = Formats.ConvertUnit(notification.Value.Value.ToString(), VswUnit.EM_CHIPLOAD_L2,1);
                        break;
                    }

                case "Sa1_Power":
                    {
                        recipeInfo.sa1Power = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa1_Temp":
                    {
                        recipeInfo.sa1Temp = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa1_Height":
                    {
                        recipeInfo.sa1Height = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa1_Freq":
                    {
                        recipeInfo.sa1Freq = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa2_Power":
                    {
                        recipeInfo.sa2Power = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa2_Temp":
                    {
                        recipeInfo.sa2Temp = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa2_Height":
                    {
                        recipeInfo.sa2Height = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa2_Freq":
                    {
                        recipeInfo.sa2Freq = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa3_Power":
                    {
                        recipeInfo.sa3Power = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa3_Temp":
                    {
                        recipeInfo.sa3Temp = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa3_Height":
                    {
                        recipeInfo.sa3Height = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa3_Freq":
                    {
                        recipeInfo.sa3Freq = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa4_Power":
                    {
                        recipeInfo.sa4Power = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa4_Temp":
                    {
                        recipeInfo.sa4Temp = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa4_Height":
                    {
                        recipeInfo.sa4Height = notification.Value.Value.ToString();
                        break;
                    }

                case "Sa4_Freq":
                    {
                        recipeInfo.sa4Freq = notification.Value.Value.ToString();
                        break;
                    }

                case "Hfw_LineSpeed":
                    {
                        recipeInfo.hfwLineSpeed = notification.Value.Value.ToString();
                        break;
                    }

                case "Hfw_Power":
                    {
                        recipeInfo.HfwPower = notification.Value.Value.ToString();
                        break;
                    }

                case "Hfw_Freq":
                    {
                        recipeInfo.HfwFreq = notification.Value.Value.ToString();
                        break;
                    }

                case "HFW_VEE_X":
                    {
                        recipeInfo.HfwVee_X = notification.Value.Value.ToString();
                        break;
                    }

                //case "Sust_Ctrl_1":
                //    {
                //        recipeInfo.Sust_Ctrl_1 = notification.Value.Value.ToString();
                //        break;
                //    }

                //case "Sust_Ctrl_2":
                //    {
                //        recipeInfo.Sust_Ctrl_2 = notification.Value.Value.ToString();
                //        break;
                //    }

                //case "Strip_WD_Target":
                //    {
                //        recipeInfo.Strip_WD_Target = notification.Value.Value.ToString();
                //        break;
                //    }

                case "HFW_Mode":
                    {
                        recipeInfo.HFW_Mode = notification.Value.Value.ToString();
                        break;
                    }


                case "HFW_PreHeatPower":
                    {
                        recipeInfo.HFW_PreHeatPower = notification.Value.Value.ToString();
                        break;
                    }

                case "HFW_Temperature":
                    {
                        recipeInfo.HFW_Temperature = notification.Value.Value.ToString();
                        break;
                    }

                case "HFW_SPC_Gain":
                    {
                        recipeInfo.HFW_SPC_Gain = Formats.ConvertUnit(notification.Value.Value.ToString(), VswUnit.HFW_SPC_Gain_L2,1);
                        break;
                    }

                case "HFW_SPC_Slope":
                    {
                        recipeInfo.HFW_SPC_Slope = Formats.ConvertUnit(notification.Value.Value.ToString(), VswUnit.HFW_SPC_Slope_L2,1);
                        break;
                    }

                default:
                    {
                        break;
                    }

            }
        }


    }


    /// <summary>
    /// 限制操作最小间隔
    /// </summary>
    public class CheckMinDelay
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="delay">最小操作间隔 s</param>
        public CheckMinDelay(int delay)
        {
            lastTime = DateTime.Now.AddDays(-1);
            during = delay;
        }

        DateTime lastTime;
        int during = 0;

        /// <summary>
        /// 防止操作过于频繁
        /// </summary>
        /// <returns></returns>
        public bool ActionVaild()
        {
            DateTime actionTime = DateTime.Now;
            DateTime expierTime = lastTime.AddSeconds(during);

            if (DateTime.Compare(actionTime, expierTime) >= 0)
            {
                lastTime = DateTime.Now;
                return true;

            }
            else
                return false;

        }

    }

}
